<?php
/**微信支付模块
 * Created by PhpStorm.
 * User: 毛文科
 * Date: 2019/3/20 0020
 * Time: 18:35
 */
namespace mwechat\bind;
use mwechat\src\Curl;
use mwechat\src\MaoWeiXin;
use think\Exception;
use think\Request;

class WechatApplet extends MaoWeiXin
{
    /**获取支付签名
     * @param array签名设置数组 $array
     * @return array
     * @throws Exception
     */
    public function getPaymentSign($array=[]){
        if(!$array){
            throw new Exception('支付签名没有参数');
        }
        foreach ($array as $key=>$value){
            $this->option[$key] = $value;
        }
        if(!isset($array['nonce_str'])){
            $this->setNonceStr(uniqid());
        }
        if(!isset($array['body'])){
            $this->setBody('这是商品描述');
        }
        if(!isset($array['out_trade_no'])){
            $this->setOutTradeNo(uniqid());
        }
        if(!isset($array['total_fee'])){
            throw new Exception('没有设置金额');
        }
        $array['appid'] = $this->getAppid();
        $array['mch_id'] = $this->getMchId();
        $array['notify_url'] = $this->getNotifyUrl();
        $array['fee_type'] = $this->getFeeType();
        $array['spbill_create_ip'] = $this->getSpbillCreateIp();
        $array['trade_type'] = $this->getTradeType();

        $array['nonce_str'] = $this->getNonceStr();
        $array['sign_type'] = $this->getSignType();
        $array['body'] = $this->getBody();
        $array['out_trade_no'] = $this->getOutTradeNo();
        $array['total_fee'] = (int)((float)$this->getTotalFee()*100);

        $array['sign'] = $this->getSign($array);
        $post_xml = "<xml>";
        foreach ($array as $key=>$value){
            $post_xml .="<$key>$value</$key>";
        }
        $post_xml.="</xml>";
        $curl = new Curl();
        $array = $curl->fasong("https://api.mch.weixin.qq.com/pay/unifiedorder",1,1,$post_xml)->xml()->get();
        return $array;
    }

    /**支付签名单设置
     * @param 交易金额 $total_fee
     * @param string交易类型 $trade_type
     * @param null异步通知地址 $notify_url
     * @param string调用微信支付API的机器IP $spbill_create_ip
     * @param null商户系统内部订单号 $out_trade_no
     * @param null微信用户在商户对应appid $openid
     * @param null商品ID $product_id
     * @param null商品描述 $body
     * @param null商品详情 $detail
     * @param null附加数据 $attach
     * @param null随机字符串 $nonce_str
     * @param string签名类型 $sign_type
     * @return string
     * @throws Exception
     */
    public function staticPaymentSign($total_fee,$trade_type=null,
                                      $notify_url=null,$spbill_create_ip=null,
                                      $out_trade_no=null,$openid=null,$product_id=null,
                                      $body=null,$detail=null,$attach=null,
                                      $nonce_str=null,$sign_type=null){
        $post['appid'] = $this->getAppid();
        $post['mch_id'] = $this->getMchId();
        if($total_fee){
            $this->setTotalFee($total_fee);
        }
        $post['total_fee'] = (int)((float)$this->getTotalFee()*100);
        if($trade_type){
            $this->setTradeType($trade_type);
        }
        $post['trade_type'] = $this->getTradeType();
        if($notify_url){
            $this->setNotifyUrl($notify_url);
        }
        $post['notify_url'] = $this->getNotifyUrl();
        if($spbill_create_ip){
            $this->setSpbillCreateIp($spbill_create_ip);
        }
        $post['spbill_create_ip'] = $this->getSpbillCreateIp();
        if($out_trade_no){
            $this->setOutTradeNo($out_trade_no);
        }else{
            $this->setOutTradeNo(uniqid());
        }
        $post['out_trade_no'] = $this->getOutTradeNo();
        if($openid){
            $this->setOpenId($openid);
            $post['openid'] = $openid;
        }
        if($product_id){
            $this->setProductId($product_id);
            $post['product_id'] = $product_id;
        }
        if($body){
            $this->setBody($body);
        }
        $post['body'] = $this->getBody();
        if($detail){
            $this->setDetail($detail);
            $post['detail'] = $detail;
        }
        if($attach){
            $this->setAttach($attach);
            $post['attach'] = $attach;
        }
        if($nonce_str){
            $this->setNonceStr($nonce_str);
        }else{
            $this->setNonceStr(uniqid());
        }
        $post['nonce_str']  = $this->getNonceStr();
        if($sign_type){
            $this->setSignType($sign_type);
        }
        $post['sign_type'] = $this->getSignType();
        $post['sign'] = $this->getSign($post);
        $post_xml = "<xml>";
        foreach ($post as $key=>$value){
            $post_xml .="<$key>$value</$key>";
        }
        $post_xml.="</xml>";
        $curl = new Curl();
        $array = $curl->fasong("https://api.mch.weixin.qq.com/pay/unifiedorder",1,1,$post_xml)->xml()->get();
        if(isset($array['return_msg'])&&($array['return_msg']=='ok'||$array['return_msg']=='OK')){
            $time = (string)time();
            $newsign['appId'] = $this->getAppid();
            $newsign['nonceStr'] = $this->getNonceStr();
            $newsign['package'] = 'prepay_id='.$array['prepay_id'];
            $newsign['signType'] = 'MD5';
            $newsign['timeStamp'] =$time;
            $newsign['paySign'] = $this->getSign($newsign);
            $newsign['out_trade_no'] = $this->getOutTradeNo();
        }else{
            return $array;
        }
        return $newsign;
    }

    /**获取支付签名
     * @param array签名数据 $data
     * @param null签名类型 $type
     * @return 签名 string
     * @throws Exception
     */
    public function getSign($data=[],$type=null){
        if($type){
            $this->setSignType($type);
        }
        if(!$data){
            throw new Exception('签名没有数据');
        }
        ksort($data);
        if($this->getMchKey()){
            $data['key'] = $this->getMchKey();
        }
        $str = '';
        foreach ($data as $key=>$value){
            if(!$value){
                continue;
            }else{
                if(!$str){
                    $str = (string)$key."=$value";
                }else{
                    $str .= "&".$key."=$value";
                }
            }
        }
        $res = '';
        if($this->getSignType()=='md5'||$this->getSignType()=='MD5'){
            $res = strtoupper(md5($str));
        }elseif($this->getSignType()=='HMAC-SHA256'){
            $res = strtoupper(hash_hmac('sha256',$str));
        }
        return $res;
    }

    /**回调函数
     * @param Request $request
     * @param $func
     */
    public function HuiDiao(Request $request){
        $xml = file_get_contents("php://input");
        $xml = simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOCDATA);
        $post_data  = (array)$xml;
        $str = '<xml>
  <return_code><![CDATA[SUCCESS]]></return_code>
  <return_msg><![CDATA[OK]]></return_msg>
</xml>';
        return ['data'=>$post_data,'str'=>$str];
    }

    /**获取小程序二维码的accesstoken
     * @param string $grant_type
     * @return string
     * @throws Exception
     */
    public function authGetAccessToken($grant_type='client_credential'){
        if($grant_type){
            $this->setGrantType($grant_type);
        }
        if(cache('authaccesstoken')){
            return cache('authaccesstoken');
        }
        $appid = $this->getAppid();
        $secret = $this->getAppSecret();
        $curl = new Curl();
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=$grant_type&appid=$appid&secret=$secret";
        $array = $curl->fasong($url,1)->jsonToArray()->get();
        cache('authaccesstoken',$array['access_token'],($array['expires_in']-100));
        return $array['access_token'];
    }

    /**获取微信小程序的二维码
     * @param string页面 $page
     * @param string参数 $scene
     * @param string宽度 $width
     * @return string
     * @throws Exception
     */
    public function getQrCode($page='pages/index/index',$scene='',$width='430'){
        $access = $this->authGetAccessToken('client_credential');
        $url ="https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=$access";
        $data = [];
        $data['page'] = $page;
        $data['scene'] = $scene;
        $data['width'] = $width;
        $data['is_hyaline'] = true;
        $data = json_encode($data);
        $curl = new Curl();
        $array = $curl->fasong($url,1,1,$data)->get();
        return $array;
    }

    /**发送模板消息
     * @param 用户openid $openid
     * @param string模本id $template_id
     * @param fromid $form_id
     * @param string跳转地点 $page
     * @param null数据包 $data
     * @return string
     * @throws Exception
     */
    public function sendTemplate($openid,$template_id,$form_id,$page='index',$data=null){
        $access_token = $this->authGetAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=$access_token";
        $str['access_token']= $access_token;
        $str['touser']= $openid;
        $str['template_id']= $template_id;
        $str['page']= $page;
        $str['form_id']= $form_id;
        $str['data']= $data;
        $str = json_encode($str);
        $curl = new Curl();
        $array = $curl->fasong($url,1,1,$str)->jsonToArray()->get();
        return $array;

    }
}